package com.lft.juc09.pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Executors 工具类、3大方法
 * 使用了线程池之后，使用线程池来创建线程。
 * <p>
 * // 拒绝策略1，队列满了，不处理任务，抛出异常。
 * new ThreadPoolExecutor.AbortPolicy());
 * // 拒绝策略2，队列满了，任务是哪个线程来的，退回哪个线程去处理。
 * new ThreadPoolExecutor.CallerRunsPolicy());
 * // 拒绝策略3，队列满了，丢掉任务，不会抛出异常！
 * new ThreadPoolExecutor.DiscardPolicy());
 * // 拒绝策略4，队列满了，尝试去和最早的竞争，也不会抛出异常！
 * new ThreadPoolExecutor.DiscardOldestPolicy());
 */
public class TestExecutors {
	public static void main(String[] args) {
		// // 使用线程池工具类
		// 单个线程
		// ExecutorService threadPool = Executors.newSingleThreadExecutor();
		// 固定线程数量的线程池
		// ExecutorService threadPool = Executors.newFixedThreadPool(5);
		// 可伸缩的线程池。
		// ExecutorService threadPool = Executors.newCachedThreadPool();
		// DiscardPolicy
		
		// // 手动创建线程池
		ExecutorService threadPool = new ThreadPoolExecutor(
				2,
				// 最大线程池大小该如何定义：
				// 1. CPU 密集型：CPU是几线程，就定义为几。可以保持CPU的效率最高。
				// 获取CPU可以处理器数。
				// 2. IO 密集型：判断程序中十分耗IO的线程。只要大于这些线程数（一般是1倍）。
				Runtime.getRuntime().availableProcessors(),
				10,
				TimeUnit.SECONDS,
				new LinkedBlockingQueue<>(3),
				Executors.defaultThreadFactory(),
				// 拒绝策略，队列满了，尝试去和最早的竞争，也不会抛出异常！
				new ThreadPoolExecutor.DiscardOldestPolicy());
		
		try {
			// 最大承载：队列 + maximumPoolSize
			for (int i = 1; i <= 9; i++) {
				threadPool.execute(() -> {
					System.out.println(Thread.currentThread().getName() + " OK");
				});
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 线程池用完，程序结束，需要关闭线程池。
			threadPool.shutdown();
		}
	}
}
